<?php

namespace App\Common\Guzzle;

use Exception;
use GuzzleHttp\Client;
use Psr\Http\Message\ResponseInterface;
use GuzzleHttp\Exception\RequestException;

class GuzzleClient
{

    private static $instance;

    public static function get()
    {
        if (!self::$instance) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    /**
     * 同步请求
     * 
     */
    public function seedRequest(
        string $method,
        string $url,
        array $param = [],
        array $header = [],
        bool $isJson = true,
        array $clientConfig = []
    ) {

        try {
            $client = new Client($clientConfig);
            $request = [];
            $upperMethod = strtoupper($method);
            if (!empty($header)) {
                $request['headers'] = $header;
            }
            if ('GET' == $upperMethod) {
                $request['query'] = $param;
            }
            $json = $isJson ? 'json' : 'form_params';
            if ('POST' == $upperMethod || 'PUT' == $upperMethod) {
                $request[$json] = $param;
            }
            $httpResult = $client->request($upperMethod, $url, $request);
            if ($httpResult->getStatusCode() == 200) {
                return json_decode($httpResult->getBody()->getContents(), true);
            } else {
                throw new Exception(REQUEST_WAS_ABORTED, 501);
            }
        } catch (Exception $ex) {
            return $ex->getMessage();
        }
    }

    /**
     * 异步请求 用于异步通知
     * 
     */
    public function asynSeedRequest(
        string $method,
        string $url,
        array $param = [],
        array $header = [],
        bool $is_json = true,
        array $clientConfig = []
    ) {
        try {
            $client = new Client($clientConfig);
            $request = [];
            $upperMethod = strtoupper($method);
            if (!empty($header)) {
                $request['headers'] = $header;
            }
            if ('GET' == $upperMethod) {
                $request['query'] = $param;
            }
            $json = $is_json ? 'json' : 'form_params';
            if ('POST' == $upperMethod || 'PUT' == $upperMethod) {
                $request[$json] = $param;
            }
            $promise = $client->requestAsync($upperMethod, $url, $request);
            $promise->then(
                function (ResponseInterface $query) {
                    if ($query->getStatusCode() == 200) {
                        echo $query->getBody()->getContents();
                    } else {
                        throw new Exception(REQUEST_WAS_ABORTED, 501);
                    }
                },
                function (RequestException $e) {
                    throw new Exception($e->getMessage(), 501);
                }
            );
            $promise->wait();
        } catch (Exception $ex) {
            return $ex->getMessage();
        }
    }
}
